Desktop/Copy of GPS_TRACE/SRC/lcd.c

Go to the documentation of this file.
00001 /****************************************************************************
00002  Title  :   HD44780U LCD library
00003  Author:    Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
00004  File:      $Id: lcd.c,v 1.14.2.1 2006/01/29 12:16:41 peter Exp $
00005  Software:  AVR-GCC 3.3 
00006  Target:    any AVR device, memory mapped mode only for AT90S4414/8515/Mega
00007 
00008  DESCRIPTION
00009        Basic routines for interfacing a HD44780U-based text lcd display
00010 
00011        Originally based on Volker Oth's lcd library,
00012        changed lcd_init(), added additional constants for lcd_command(),
00013        added 4-bit I/O mode, improved and optimized code.
00014 
00015        Library can be operated in memory mapped mode (LCD_IO_MODE=0) or in 
00016        4-bit IO port mode (LCD_IO_MODE=1). 8-bit IO port mode not supported.
00017        
00018        Memory mapped mode compatible with Kanda STK200, but supports also
00019        generation of R/W signal through A8 address line.
00020 
00021  USAGE
00022        See the C include lcd.h file for a description of each function
00023        
00024 *****************************************************************************/
00025 #include <inttypes.h>
00026 #include <avr/io.h>
00027 #include <avr/pgmspace.h>
00028 #include "lcd.h"
00029 
00030 
00031 
00032 /* 
00033 ** constants/macros 
00034 */
00035 #define DDR(x) (*(&x - 1))      /* address of data direction register of port x */
00036 #if defined(__AVR_ATmega64__) || defined(__AVR_ATmega128__)
00037     /* on ATmega64/128 PINF is on port 0x00 and not 0x60 */
00038     #define PIN(x) ( &PORTF==&(x) ? _SFR_IO8(0x00) : (*(&x - 2)) )
00039 #else
00040         #define PIN(x) (*(&x - 2))    /* address of input register of port x          */
00041 #endif
00042 
00043 
00044 #if LCD_IO_MODE
00045 #define lcd_e_delay()   __asm__ __volatile__( "rjmp 1f\n 1:" );
00046 #define lcd_e_high()    LCD_E_PORT  |=  _BV(LCD_E_PIN);
00047 #define lcd_e_low()     LCD_E_PORT  &= ~_BV(LCD_E_PIN);
00048 #define lcd_e_toggle()  toggle_e()
00049 #define lcd_rw_high()   LCD_RW_PORT |=  _BV(LCD_RW_PIN)
00050 #define lcd_rw_low()    LCD_RW_PORT &= ~_BV(LCD_RW_PIN)
00051 #define lcd_rs_high()   LCD_RS_PORT |=  _BV(LCD_RS_PIN)
00052 #define lcd_rs_low()    LCD_RS_PORT &= ~_BV(LCD_RS_PIN)
00053 #endif
00054 
00055 #if LCD_IO_MODE
00056 #if LCD_LINES==1
00057 #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_1LINE 
00058 #else
00059 #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_4BIT_2LINES 
00060 #endif
00061 #else
00062 #if LCD_LINES==1
00063 #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_8BIT_1LINE
00064 #else
00065 #define LCD_FUNCTION_DEFAULT    LCD_FUNCTION_8BIT_2LINES
00066 #endif
00067 #endif
00068 
00069 #if LCD_CONTROLLER_KS0073
00070 #if LCD_LINES==4
00071 
00072 #define KS0073_EXTENDED_FUNCTION_REGISTER_ON  0x24   /* |0|010|0100 4-bit mode extension-bit RE = 1 */
00073 #define KS0073_EXTENDED_FUNCTION_REGISTER_OFF 0x20   /* |0|000|1001 4 lines mode */
00074 #define KS0073_4LINES_MODE                    0x09   /* |0|001|0000 4-bit mode, extension-bit RE = 0 */
00075 
00076 #endif
00077 #endif
00078 
00079 /* 
00080 ** function prototypes 
00081 */
00082 #if LCD_IO_MODE
00083 static void toggle_e(void);
00084 #endif
00085 
00086 /*
00087 ** local functions
00088 */
00089 
00090 
00091 
00092 /*************************************************************************
00093  delay loop for small accurate delays: 16-bit counter, 4 cycles/loop
00094 *************************************************************************/
00095 static inline void _delayFourCycles(unsigned int __count)
00096 {
00097     if ( __count == 0 )    
00098         __asm__ __volatile__( "rjmp 1f\n 1:" );    // 2 cycles
00099     else
00100         __asm__ __volatile__ (
00101             "1: sbiw %0,1" "\n\t"                  
00102             "brne 1b"                              // 4 cycles/loop
00103             : "=w" (__count)
00104             : "0" (__count)
00105            );
00106 }
00107 
00108 
00109 /************************************************************************* 
00110 delay for a minimum of <us> microseconds
00111 the number of loops is calculated at compile-time from MCU clock frequency
00112 *************************************************************************/
00113 #define delay(us)  _delayFourCycles( ( ( 1*(XTAL/4000) )*us)/1000 )
00114 
00115 
00116 #if LCD_IO_MODE
00117 /* toggle Enable Pin to initiate write */
00118 static void toggle_e(void)
00119 {
00120     lcd_e_high();
00121     lcd_e_delay();
00122     lcd_e_low();
00123 }
00124 #endif
00125 
00126 
00127 /*************************************************************************
00128 Low-level function to write byte to LCD controller
00129 Input:    data   byte to write to LCD
00130           rs     1: write data    
00131                  0: write instruction
00132 Returns:  none
00133 *************************************************************************/
00134 #if LCD_IO_MODE
00135 static void lcd_write(uint8_t data,uint8_t rs) 
00136 {
00137     unsigned char dataBits ;
00138 
00139 
00140     if (rs) {   /* write data        (RS=1, RW=0) */
00141        lcd_rs_high();
00142     } else {    /* write instruction (RS=0, RW=0) */
00143        lcd_rs_low();
00144     }
00145     lcd_rw_low();
00146 
00147     if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
00148       && (LCD_DATA0_PIN == 0) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
00149     {
00150         /* configure data pins as output */
00151         DDR(LCD_DATA0_PORT) |= 0x0F;
00152 
00153         /* output high nibble first */
00154         dataBits = LCD_DATA0_PORT & 0xF0;
00155         LCD_DATA0_PORT = dataBits |((data>>4)&0x0F);
00156         lcd_e_toggle();
00157 
00158         /* output low nibble */
00159         LCD_DATA0_PORT = dataBits | (data&0x0F);
00160         lcd_e_toggle();
00161 
00162         /* all data pins high (inactive) */
00163         LCD_DATA0_PORT = dataBits | 0x0F;
00164     }
00165     else
00166     {
00167         /* configure data pins as output */
00168         DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
00169         DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
00170         DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
00171         DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
00172         
00173         /* output high nibble first */
00174         LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
00175         LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
00176         LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
00177         LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
00178         if(data & 0x80) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
00179         if(data & 0x40) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
00180         if(data & 0x20) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
00181         if(data & 0x10) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);   
00182         lcd_e_toggle();
00183         
00184         /* output low nibble */
00185         LCD_DATA3_PORT &= ~_BV(LCD_DATA3_PIN);
00186         LCD_DATA2_PORT &= ~_BV(LCD_DATA2_PIN);
00187         LCD_DATA1_PORT &= ~_BV(LCD_DATA1_PIN);
00188         LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);
00189         if(data & 0x08) LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
00190         if(data & 0x04) LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
00191         if(data & 0x02) LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
00192         if(data & 0x01) LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
00193         lcd_e_toggle();        
00194         
00195         /* all data pins high (inactive) */
00196         LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);
00197         LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);
00198         LCD_DATA2_PORT |= _BV(LCD_DATA2_PIN);
00199         LCD_DATA3_PORT |= _BV(LCD_DATA3_PIN);
00200     }
00201 }
00202 #else
00203 #define lcd_write(d,rs) if (rs) *(volatile uint8_t*)(LCD_IO_DATA) = d; else *(volatile uint8_t*)(LCD_IO_FUNCTION) = d;
00204 /* rs==0 -> write instruction to LCD_IO_FUNCTION */
00205 /* rs==1 -> write data to LCD_IO_DATA */
00206 #endif
00207 
00208 
00209 /*************************************************************************
00210 Low-level function to read byte from LCD controller
00211 Input:    rs     1: read data    
00212                  0: read busy flag / address counter
00213 Returns:  byte read from LCD controller
00214 *************************************************************************/
00215 #if LCD_IO_MODE
00216 static uint8_t lcd_read(uint8_t rs) 
00217 {
00218     uint8_t data;
00219     
00220     
00221     if (rs)
00222         lcd_rs_high();                       /* RS=1: read data      */
00223     else
00224         lcd_rs_low();                        /* RS=0: read busy flag */
00225     lcd_rw_high();                           /* RW=1  read mode      */
00226     
00227     if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
00228       && ( LCD_DATA0_PIN == 0 )&& (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
00229     {
00230         DDR(LCD_DATA0_PORT) &= 0xF0;         /* configure data pins as input */
00231         
00232         lcd_e_high();
00233         lcd_e_delay();        
00234         data = PIN(LCD_DATA0_PORT) << 4;     /* read high nibble first */
00235         lcd_e_low();
00236         
00237         lcd_e_delay();                       /* Enable 500ns low       */
00238         
00239         lcd_e_high();
00240         lcd_e_delay();
00241         data |= PIN(LCD_DATA0_PORT)&0x0F;    /* read low nibble        */
00242         lcd_e_low();
00243     }
00244     else
00245     {
00246         /* configure data pins as input */
00247         DDR(LCD_DATA0_PORT) &= ~_BV(LCD_DATA0_PIN);
00248         DDR(LCD_DATA1_PORT) &= ~_BV(LCD_DATA1_PIN);
00249         DDR(LCD_DATA2_PORT) &= ~_BV(LCD_DATA2_PIN);
00250         DDR(LCD_DATA3_PORT) &= ~_BV(LCD_DATA3_PIN);
00251                 
00252         /* read high nibble first */
00253         lcd_e_high();
00254         lcd_e_delay();        
00255         data = 0;
00256         if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x10;
00257         if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x20;
00258         if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x40;
00259         if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x80;
00260         lcd_e_low();
00261 
00262         lcd_e_delay();                       /* Enable 500ns low       */
00263     
00264         /* read low nibble */    
00265         lcd_e_high();
00266         lcd_e_delay();
00267         if ( PIN(LCD_DATA0_PORT) & _BV(LCD_DATA0_PIN) ) data |= 0x01;
00268         if ( PIN(LCD_DATA1_PORT) & _BV(LCD_DATA1_PIN) ) data |= 0x02;
00269         if ( PIN(LCD_DATA2_PORT) & _BV(LCD_DATA2_PIN) ) data |= 0x04;
00270         if ( PIN(LCD_DATA3_PORT) & _BV(LCD_DATA3_PIN) ) data |= 0x08;        
00271         lcd_e_low();
00272     }
00273     return data;
00274 }
00275 #else
00276 #define lcd_read(rs) (rs) ? *(volatile uint8_t*)(LCD_IO_DATA+LCD_IO_READ) : *(volatile uint8_t*)(LCD_IO_FUNCTION+LCD_IO_READ)
00277 /* rs==0 -> read instruction from LCD_IO_FUNCTION */
00278 /* rs==1 -> read data from LCD_IO_DATA */
00279 #endif
00280 
00281 
00282 /*************************************************************************
00283 loops while lcd is busy, returns address counter
00284 *************************************************************************/
00285 static uint8_t lcd_waitbusy(void)
00286 
00287 {
00288     register uint8_t c;
00289     
00290     /* wait until busy flag is cleared */
00291     while ( (c=lcd_read(0)) & (1<<LCD_BUSY)) {}
00292     
00293     /* the address counter is updated 4us after the busy flag is cleared */
00294     delay(2);
00295 
00296     /* now read the address counter */
00297     return (lcd_read(0));  // return address counter
00298     
00299 }/* lcd_waitbusy */
00300 
00301 
00302 /*************************************************************************
00303 Move cursor to the start of next line or to the first line if the cursor 
00304 is already on the last line.
00305 *************************************************************************/
00306 static inline void lcd_newline(uint8_t pos)
00307 {
00308     register uint8_t addressCounter;
00309 
00310 
00311 #if LCD_LINES==1
00312     addressCounter = 0;
00313 #endif
00314 #if LCD_LINES==2
00315     if ( pos < (LCD_START_LINE2) )
00316         addressCounter = LCD_START_LINE2;
00317     else
00318         addressCounter = LCD_START_LINE1;
00319 #endif
00320 #if LCD_LINES==4
00321 #if KS0073_4LINES_MODE
00322     if ( pos < LCD_START_LINE2 )
00323         addressCounter = LCD_START_LINE2;
00324     else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE3) )
00325         addressCounter = LCD_START_LINE3;
00326     else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE4) )
00327         addressCounter = LCD_START_LINE4;
00328     else 
00329         addressCounter = LCD_START_LINE1;
00330 #else
00331     if ( pos < LCD_START_LINE3 )
00332         addressCounter = LCD_START_LINE2;
00333     else if ( (pos >= LCD_START_LINE2) && (pos < LCD_START_LINE4) )
00334         addressCounter = LCD_START_LINE3;
00335     else if ( (pos >= LCD_START_LINE3) && (pos < LCD_START_LINE2) )
00336         addressCounter = LCD_START_LINE4;
00337     else 
00338         addressCounter = LCD_START_LINE1;
00339 #endif
00340 #endif
00341     lcd_command((1<<LCD_DDRAM)+addressCounter);
00342 
00343 }/* lcd_newline */
00344 
00345 
00346 /*
00347 ** PUBLIC FUNCTIONS 
00348 */
00349 
00350 /*************************************************************************
00351 Send LCD controller instruction command
00352 Input:   instruction to send to LCD controller, see HD44780 data sheet
00353 Returns: none
00354 *************************************************************************/
00355 void lcd_command(uint8_t cmd)
00356 {
00357     lcd_waitbusy();
00358     lcd_write(cmd,0);
00359 }
00360 
00361 
00362 /*************************************************************************
00363 Send data byte to LCD controller 
00364 Input:   data to send to LCD controller, see HD44780 data sheet
00365 Returns: none
00366 *************************************************************************/
00367 void lcd_data(uint8_t data)
00368 {
00369     lcd_waitbusy();
00370     lcd_write(data,1);
00371 }
00372 
00373 
00374 
00375 /*************************************************************************
00376 Set cursor to specified position
00377 Input:    x  horizontal position  (0: left most position)
00378           y  vertical position    (0: first line)
00379 Returns:  none
00380 *************************************************************************/
00381 void lcd_gotoxy(uint8_t x, uint8_t y)
00382 {
00383 #if LCD_LINES==1
00384     lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00385 #endif
00386 #if LCD_LINES==2
00387     if ( y==0 ) 
00388         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00389     else
00390         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
00391 #endif
00392 #if LCD_LINES==4
00393     if ( y==0 )
00394         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE1+x);
00395     else if ( y==1)
00396         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE2+x);
00397     else if ( y==2)
00398         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE3+x);
00399     else /* y==3 */
00400         lcd_command((1<<LCD_DDRAM)+LCD_START_LINE4+x);
00401 #endif
00402 
00403 }/* lcd_gotoxy */
00404 
00405 
00406 /*************************************************************************
00407 *************************************************************************/
00408 int lcd_getxy(void)
00409 {
00410     return lcd_waitbusy();
00411 }
00412 
00413 
00414 /*************************************************************************
00415 Clear display and set cursor to home position
00416 *************************************************************************/
00417 void lcd_clrscr(void)
00418 {
00419     lcd_command(1<<LCD_CLR);
00420 }
00421 
00422 
00423 /*************************************************************************
00424 Set cursor to home position
00425 *************************************************************************/
00426 void lcd_home(void)
00427 {
00428     lcd_command(1<<LCD_HOME);
00429 }
00430 
00431 
00432 /*************************************************************************
00433 Display character at current cursor position 
00434 Input:    character to be displayed                                       
00435 Returns:  none
00436 *************************************************************************/
00437 void lcd_putc(char c)
00438 {
00439     uint8_t pos;
00440 
00441 
00442     pos = lcd_waitbusy();   // read busy-flag and address counter
00443     if (c=='\n')
00444     {
00445         lcd_newline(pos);
00446     }
00447     else
00448     {
00449 #if LCD_WRAP_LINES==1
00450 #if LCD_LINES==1
00451         if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
00452             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
00453         }
00454 #elif LCD_LINES==2
00455         if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
00456             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
00457         }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ){
00458             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
00459         }
00460 #elif LCD_LINES==4
00461         if ( pos == LCD_START_LINE1+LCD_DISP_LENGTH ) {
00462             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE2,0);    
00463         }else if ( pos == LCD_START_LINE2+LCD_DISP_LENGTH ) {
00464             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE3,0);
00465         }else if ( pos == LCD_START_LINE3+LCD_DISP_LENGTH ) {
00466             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE4,0);
00467         }else if ( pos == LCD_START_LINE4+LCD_DISP_LENGTH ) {
00468             lcd_write((1<<LCD_DDRAM)+LCD_START_LINE1,0);
00469         }
00470 #endif
00471         lcd_waitbusy();
00472 #endif
00473         lcd_write(c, 1);
00474     }
00475 
00476 }/* lcd_putc */
00477 
00478 
00479 /*************************************************************************
00480 Display string without auto linefeed 
00481 Input:    string to be displayed
00482 Returns:  none
00483 *************************************************************************/
00484 void lcd_puts(const char *s)
00485 /* print string on lcd (no auto linefeed) */
00486 {
00487     register char c;
00488 
00489     while ( (c = *s++) ) {
00490         lcd_putc(c);
00491     }
00492 
00493 }/* lcd_puts */
00494 
00495 
00496 /*************************************************************************
00497 Display string from program memory without auto linefeed 
00498 Input:     string from program memory be be displayed                                        
00499 Returns:   none
00500 *************************************************************************/
00501 void lcd_puts_p(const char *progmem_s)
00502 /* print string from program memory on lcd (no auto linefeed) */
00503 {
00504     register char c;
00505 
00506     while ( (c = pgm_read_byte(progmem_s++)) ) {
00507         lcd_putc(c);
00508     }
00509 
00510 }/* lcd_puts_p */
00511 
00512 
00513 /*************************************************************************
00514 Initialize display and select type of cursor 
00515 Input:    dispAttr LCD_DISP_OFF            display off
00516                    LCD_DISP_ON             display on, cursor off
00517                    LCD_DISP_ON_CURSOR      display on, cursor on
00518                    LCD_DISP_CURSOR_BLINK   display on, cursor on flashing
00519 Returns:  none
00520 *************************************************************************/
00521 void lcd_init(uint8_t dispAttr)
00522 {
00523 #if LCD_IO_MODE
00524     /*
00525      *  Initialize LCD to 4 bit I/O mode
00526      */
00527      
00528     if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
00529       && ( &LCD_RS_PORT == &LCD_DATA0_PORT) && ( &LCD_RW_PORT == &LCD_DATA0_PORT) && (&LCD_E_PORT == &LCD_DATA0_PORT)
00530       && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) 
00531       && (LCD_RS_PIN == 4 ) && (LCD_RW_PIN == 5) && (LCD_E_PIN == 6 ) )
00532     {
00533         /* configure all port bits as output (all LCD lines on same port) */
00534         DDR(LCD_DATA0_PORT) |= 0x7F;
00535     }
00536     else if ( ( &LCD_DATA0_PORT == &LCD_DATA1_PORT) && ( &LCD_DATA1_PORT == &LCD_DATA2_PORT ) && ( &LCD_DATA2_PORT == &LCD_DATA3_PORT )
00537            && (LCD_DATA0_PIN == 0 ) && (LCD_DATA1_PIN == 1) && (LCD_DATA2_PIN == 2) && (LCD_DATA3_PIN == 3) )
00538     {
00539         /* configure all port bits as output (all LCD data lines on same port, but control lines on different ports) */
00540         DDR(LCD_DATA0_PORT) |= 0x0F;
00541         DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
00542         DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
00543         DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
00544     }
00545     else
00546     {
00547         /* configure all port bits as output (LCD data and control lines on different ports */
00548         DDR(LCD_RS_PORT)    |= _BV(LCD_RS_PIN);
00549         DDR(LCD_RW_PORT)    |= _BV(LCD_RW_PIN);
00550         DDR(LCD_E_PORT)     |= _BV(LCD_E_PIN);
00551         DDR(LCD_DATA0_PORT) |= _BV(LCD_DATA0_PIN);
00552         DDR(LCD_DATA1_PORT) |= _BV(LCD_DATA1_PIN);
00553         DDR(LCD_DATA2_PORT) |= _BV(LCD_DATA2_PIN);
00554         DDR(LCD_DATA3_PORT) |= _BV(LCD_DATA3_PIN);
00555     }
00556     delay(16000);        /* wait 16ms or more after power-on       */
00557     
00558     /* initial write to lcd is 8bit */
00559     LCD_DATA1_PORT |= _BV(LCD_DATA1_PIN);  // _BV(LCD_FUNCTION)>>4;
00560     LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
00561     lcd_e_toggle();
00562     delay(4992);         /* delay, busy flag can't be checked here */
00563    
00564     /* repeat last command */ 
00565     lcd_e_toggle();      
00566     delay(64);           /* delay, busy flag can't be checked here */
00567     
00568     /* repeat last command a third time */
00569     lcd_e_toggle();      
00570     delay(64);           /* delay, busy flag can't be checked here */
00571 
00572     /* now configure for 4bit mode */
00573     LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);   // LCD_FUNCTION_4BIT_1LINE>>4
00574     lcd_e_toggle();
00575     delay(64);           /* some displays need this additional delay */
00576     
00577     /* from now the LCD only accepts 4 bit I/O, we can use lcd_command() */    
00578 #else
00579     /*
00580      * Initialize LCD to 8 bit memory mapped mode
00581      */
00582     
00583     /* enable external SRAM (memory mapped lcd) and one wait state */        
00584     MCUCR = _BV(SRE) | _BV(SRW);
00585 
00586     /* reset LCD */
00587     delay(16000);                           /* wait 16ms after power-on     */
00588     lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                   
00589     delay(4992);                            /* wait 5ms                     */
00590     lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                 
00591     delay(64);                              /* wait 64us                    */
00592     lcd_write(LCD_FUNCTION_8BIT_1LINE,0);   /* function set: 8bit interface */                
00593     delay(64);                              /* wait 64us                    */
00594 #endif
00595 
00596 #if KS0073_4LINES_MODE
00597     /* Display with KS0073 controller requires special commands for enabling 4 line mode */
00598         lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_ON);
00599         lcd_command(KS0073_4LINES_MODE);
00600         lcd_command(KS0073_EXTENDED_FUNCTION_REGISTER_OFF);
00601 #else
00602     lcd_command(LCD_FUNCTION_DEFAULT);      /* function set: display lines  */
00603 #endif
00604     lcd_command(LCD_DISP_OFF);              /* display off                  */
00605     lcd_clrscr();                           /* display clear                */ 
00606     lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
00607     lcd_command(dispAttr);                  /* display/cursor control       */
00608 
00609 }/* lcd_init */

Generated on Fri Aug 17 13:50:54 2007 for GPS TRACE by  doxygen 1.5.3